#include <fstream>
#include <sstream>
#include <iomanip>
#include "Banco.h"

Banco::Banco()
{
}

Banco::~Banco()
{
}

istream &operator>>(istream &is, ContaCorrente &contc)
{
	string campo, linha;
	int tmp;
	string tmp2;
	double aux;
	size_t pos, pos_a = 0;
	getline(is, linha);
// Codigo
	pos = linha.find(';');
	campo = linha.substr(pos_a,pos);
	stringstream cd;
	cd << campo ;
	cd >> tmp;
	contc.SetCodigo(tmp);
// CPF
	pos_a = pos;
	pos = linha.find(';', pos_a+1);
	campo = linha.substr(pos_a+1,pos-pos_a-1);
	stringstream cpf;
	cpf << campo ;
	cpf >> tmp2;	
	contc.SetCPF(tmp2);
// Saldo
	pos_a = pos;
	pos = linha.find(";", pos_a+1);
	campo = linha.substr(pos_a+1,pos-pos_a-1);
	stringstream sald;
	sald << campo;
	sald >> aux;
	contc.SetSaldo(aux);
// Limite
	pos_a = pos;
	pos = linha.find(";", pos_a+1);
	campo = linha.substr(pos_a+1,pos-pos_a-1);
	stringstream lim;
	lim << campo;
	lim >> aux;
	contc.SetLimite(aux);
	return is;	
}

ostream &operator<<(ostream &os, const ContaCorrente &contc)
{
	os << "\t| " << setw(10) << contc.GetCodigo() 
	    << " | R$" << setw(10) << fixed << setprecision(2) << contc.GetSaldo() 
	    << " | " << setw(11) << fixed << setprecision(12) << contc.GetCPF() 
	    << " | R$" << setw(10) << fixed << setprecision(2) << contc.GetLimite() << " |";
	return os;	
}

void Banco::CadastraNovaConta(int codigo)
{
	ContaCorrente contc;
//Atribui o codigo recebido a nova conta
	contc.SetCodigo(codigo);
	string cpf;
	double saldo;
	double limite;
	cout << endl << "Digite CPF: ";
	cin >> cpf;
//Insere CPF a nova conta
	contc.SetCPF(cpf);
	cout << endl << "Digite Saldo: ";
	cin >> saldo;
//Insere CPF a nova conta
	contc.SetSaldo(saldo);
	cout << endl << "Digite Limite: ";
	cin >> limite;
//Insere CPF a nova conta
	contc.SetLimite(limite);
//Insere nova conta ao vetor
	Contas.Insere(contc);
}

void Banco::CarregaContas(string NomeArquivo)
{
	try 
	{
		fstream arq(NomeArquivo.c_str(), fstream::in);
		string str;
		ContaCorrente contc;
		getline(arq, str); // pular a primeira linha!!!!
		while(! arq.eof() )
		{
			arq >> contc;
			Contas.Insere(contc);		
		}		
	} 
	catch (ExcecaoVetor e) 
	{
		cerr << endl << "Erro no vetor Contas: " << e.what();
	}
	catch (runtime_error e)
	{
		cerr << endl << "Erro: " << e.what();	
	}		
}

void Banco::GravaContas()
{
	fstream arq("SaldoBancario.dat", fstream::out);
	arq << "Codigo;CPF;Saldo;Limite;";
	for(int i = 0 ; i < Contas.GetNumValores(); i++)
	{  
		arq	<<endl<< Contas[i].GetCodigo() << ";"
			<< Contas[i].GetCPF() << ";"
			<< Contas[i].GetSaldo() << ";"
			<< Contas[i].GetLimite() << ";";
	}
	arq.close();
}

void Banco::SetLimite(int i,double limite)
{
	Contas[i].SetLimite(limite);
}

int Banco::GetNumContas()
{
	return Contas.GetNumValores();
}

int Banco::GetCodigo(int i)
{
	return Contas[i].GetCodigo();
}

double Banco::GetSaldo(int i)
{
	return Contas[i].GetSaldo();
}

double Banco::GetLimite(int i)
{
	return Contas[i].GetLimite();
}

ContaCorrente Banco::GetContaCorrente(int i)
{
	return Contas[i];	
}





void Banco::ApresentaContas()
{
	cout << endl << "\t\t--- Lista de Contas Cadastradas ---" << endl;
//linha superior
	cout << "\t|" << setw(57) << setfill('-') << "|" << setfill(' ');
//--Cabecalho
	cout << endl << "\t| " << setw(10) << left << "Conta no." 
	              << " | " << setw(12)<< left << "Saldo" 
	              << " | " << setw(11) << left << "CPF" 
	              << " | " << setw(12) << left << "Limite" << " |"; 
//linha do meio
	cout << endl << "\t|" << right << setw(57) << setfill('-') << "|" << setfill(' ') << endl;
//Dados	
	for(int i = 0; 	i < Contas.GetNumValores(); i++)
		cout << Contas[i] << endl;	
//linha inferior
	cout << "\t|" << right << setw(57) << setfill('-') << "|" << setfill(' ') << endl;
}
